/*
 * Copyright (c) 2009, Manish Shakya,Real Time Solutions Pvt. Ltd.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the Institute nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *
 */
/*!
        \file 		timer.c
        \author		Manish Shakya	<A HREF="http://www.manishshakya.com.np">My website<A>
        \brief		Basic Routines for Timer 0 and Timer 1 

    
*/
#include "peripherals.h"
//#include "timer32.h"
#ifdef __TIMER32__

#define TXIR(X)           (*((volatile unsigned char *) (0xE0004000+((X)*0x4000))))
#define TXTCR(X)          (*((volatile unsigned char *) (0xE0004004+((X)*0x4000))))
#define TXTC(X)           (*((volatile unsigned long *) (0xE0004008+((X)*0x4000))))
#define TXPR(X)           (*((volatile unsigned long *) (0xE000400C+((X)*0x4000))))
#define TXPC(X)           (*((volatile unsigned long *) (0xE0004010+((X)*0x4000))))
#define TXMCR(X)          (*((volatile unsigned short*) (0xE0004014+((X)*0x4000))))
#define TXMR0(X)          (*((volatile unsigned long *) (0xE0004018+((X)*0x4000))))
#define TXMR1(X)          (*((volatile unsigned long *) (0xE000401C+((X)*0x4000))))
#define TXMR2(X)          (*((volatile unsigned long *) (0xE0004020+((X)*0x4000))))
#define TXMR3(X)          (*((volatile unsigned long *) (0xE0004024+((X)*0x4000))))
#define TXCCR(X)          (*((volatile unsigned short*) (0xE0004028+((X)*0x4000))))
#define TXCR0(X)          (*((volatile unsigned long *) (0xE000402C+((X)*0x4000))))
#define TXCR1(X)          (*((volatile unsigned long *) (0xE0004030+((X)*0x4000))))
#define TXCR2(X)          (*((volatile unsigned long *) (0xE0004034+((X)*0x4000))))
#define TXCR3(X)          (*((volatile unsigned long *) (0xE0004038+((X)*0x4000))))
#define TXEMR(X)          (*((volatile unsigned short*) (0xE000403C+((X)*0x4000))))
#define TXCTCR(X)         (*((volatile unsigned char *) (0xE0004070+((X)*0x4000))))
#define TXPWMCON(X)       (*((volatile unsigned long *) (0xE0004074+((X)*0x4000))))

/***********************************************************************************************************************/
/*!
    \name	timer32_Init
    \param	timer	    TIMER0 or TIMER1 	
    \param	ptr	        pointer to timer settings struct
    \param	handler	    pointer to function to isr routine
    \return	 none
    \sa

*/
#ifdef TIMER0_MATCH0_RELOAD
	extern void timer0_match_register0(void);
#else
	#define timer0_match_register0()	{;}
	#define TIMER0_MATCH0_RELOAD		0
#endif

#ifdef TIMER0_MATCH1_RELOAD
	extern void timer0_match_register1(void);
#else
	#define timer0_match_register1()	{;}
	#define TIMER0_MATCH1_RELOAD		0
#endif

#ifdef TIMER0_MATCH2_RELOAD
	extern void timer0_match_register2(void);
#else
	#define timer0_match_register2()	{;}
	#define TIMER0_MATCH2_RELOAD		0
#endif

#ifdef TIMER0_MATCH3_RELOAD
	extern void timer0_match_register3(void);
#else
	#define timer0_match_register3()	{;}
	#define TIMER0_MATCH3_RELOAD		0
#endif

#ifdef TIMER1_MATCH0_RELOAD
	extern void timer1_match_register0(void);
#else
	#define timer1_match_register0()	{;}
	#define TIMER1_MATCH0_RELOAD		0
#endif

#ifdef TIMER1_MATCH1_RELOAD
	extern void timer1_match_register1(void);
#else
	#define timer1_match_register1()	{;}
	#define TIMER1_MATCH1_RELOAD		0
#endif

#ifdef TIMER1_MATCH2_RELOAD
	extern void timer1_match_register2(void);
#else
	#define timer1_match_register2()	{;}
	#define TIMER1_MATCH2_RELOAD		0
#endif

#ifdef TIMER1_MATCH3_RELOAD
	extern void timer1_match_register3(void);
#else
	#define timer1_match_register3()	{;}
	#define TIMER1_MATCH3_RELOAD		0
#endif

#if TIMER0_ENABLE == 1
__irq void
__timer0_isr()
{    
	TXTCR(0)=TIMER_RESET;
	if(TXIR(0) & MASK_MR0){
		timer0_match_register0();
		RESET_T0MR0();
	}
    if(TXIR(0) & MASK_MR1){
		timer0_match_register1();
		RESET_T0MR1();
	}
    if(TXIR(0) & MASK_MR2){
		timer0_match_register2();
		RESET_T0MR2();
	}
    if(TXIR(0) & MASK_MR3){
		timer0_match_register3();
		RESET_T0MR3();
	}
	TXTCR(0)=TIMER_ENABLE;
	RETURN_TIMER0();
}
#endif	/*TIMER0_ENABLE*/

#if TIMER1_ENABLE == 1
void
__timer1_isr()	__irq
{
	TXTCR(1)=TIMER_RESET;
	if(TXIR(1) & MASK_MR0){
		timer1_match_register0();
		RESET_T1MR0();
	}
    if(TXIR(1) & MASK_MR1){
		timer1_match_register1();
		RESET_T1MR1();
	}
    if(TXIR(1) & MASK_MR2){
		timer1_match_register2();
		RESET_T1MR2();
	}
    if(TXIR(1) & MASK_MR3){
		timer1_match_register3();
		RESET_T1MR3();
	}
	TXTCR(1)=TIMER_ENABLE;
	RETURN_TIMER1();
}
#endif	/*TIMER1_ENABLE*/

void
timer32_init(void)
{
	#if TIMER0_ENABLE == 1
	{	
		timer_settings_s t={TIMER0_PRESCALER,
							 TIMER0_MATCH_CONTROL,
							 TIMER0_MATCH0_RELOAD,TIMER0_MATCH1_RELOAD,TIMER0_MATCH2_RELOAD,TIMER0_MATCH3_RELOAD};
		lpc_timer32_init(TIMER0,&t,__timer0_isr);
	}
	#endif	/*TIMER0*/

	#if TIMER1_ENABLE == 1
	{
		timer_settings_s t={TIMER1_PRESCALER,
							 TIMER1_MATCH_CONTROL,
							 TIMER1_MATCH0_RELOAD,TIMER1_MATCH1_RELOAD,TIMER1_MATCH2_RELOAD,TIMER1_MATCH3_RELOAD};
		lpc_timer32_init(TIMER1,&t,__timer1_isr);
	}
	#endif	/*TIMER1*/
}

void
lpc_timer32_init(const uint32_t timer,timer_settings_s * ptr, void (* handler)(void)__irq )
{

	TXTCR(timer)=TIMER_RESET;
	TXPR(timer)=ptr->PR;
    TXMCR(timer)=ptr->MCR;
    TXMR0(timer)=ptr->MR0;
    TXMR1(timer)=ptr->MR1;
    TXMR2(timer)=ptr->MR2;
    TXMR3(timer)=ptr->MR3;
    TXCTCR(timer)=0;
    TXTCR(timer)=TIMER_ENABLE;

    if (handler){
        irq_install(TIMER0_INT+timer,handler);
    }
}
/***********************************************************************************************************************/
/*!
    \name	timer32_disable
    \param	timer	    TIMER0 or TIMER1 	
    \return	 none
    \sa

*/


void timer32_disable(uint32_t timer)
{
	TXTCR(timer)=TIMER_RESET;
}
/***********************************************************************************************************************/

/*!
    \name	timer32_enable
    \param	timer	    TIMER0 or TIMER1 	
    \return	 none
    \sa

*/
void timer32_enable(uint32_t timer)
{
	TXTCR(timer)=TIMER_ENABLE;
}
#endif
